#pragma once
#include "Grid.h"
#include <Eigen/Dense>  // 包含 VectorXd 定义
#include <Eigen/Sparse>
#include "BoundaryConditions.h"
#include <string>

class MultigridSolver {
public:
    // 构造函数
    MultigridSolver(Grid& grid, BoundaryConditions& bc, const std::string& filename);

    // 主求解函数
    Eigen::VectorXd solve();

    // 精确解函数
    Eigen::VectorXd getExact_solution();

    // 计算误差
    double compute_error();

    void epsilon_sensitivity_test();

    // V-cycle 和 FMG-cycle
    Eigen::VectorXd vCycle(Eigen::SparseMatrix<double> A, Eigen::VectorXd v, Eigen::VectorXd f, int v1, int v2);
    Eigen::VectorXd fmgCycle(Eigen::SparseMatrix<double> A,  Eigen::VectorXd f, int v1, int v2);

private:
    Grid& grid;
    BoundaryConditions& bc;

    int n;
    int dimension;
    std::vector<double> initial_guess;
    std::vector<std::string> types;
    std::string method;        // V-cycle, FMG
    std::string restriction;   // full weighting, injection
    std::string interpolation; // linear, quadratic
    double tolerance;
    int maxIterations;
    int v1; 
    int v2; 
    Eigen::VectorXd exact_solution;
    Eigen::VectorXd solution;

    // 主要内部方法
    Eigen::VectorXd relax(int numIterations, Eigen::SparseMatrix<double> A, Eigen::VectorXd v, Eigen::VectorXd f);      // Gauss-Seidel 松弛
    Eigen::VectorXd restrict(Eigen::VectorXd v);                    // 限制操作
    Eigen::VectorXd interpolate(Eigen::VectorXd v);                 // 插值操作
    Eigen::VectorXd solveCoarsestGrid(Eigen::SparseMatrix<double> A, Eigen::VectorXd f);           // LU 分解求解最粗网格
    void loadFromJson(const std::string& filename); // 读取 JSON 文件
    Eigen::VectorXd setupVector();
    Eigen::SparseMatrix<double> setupMatrix();
    Eigen::SparseMatrix<double> setupA(int n);
};
